package debianpackager

import (
	"bytes"
	"fmt"
	"os"
	"path/filepath"
	"reflect"
)

type FieldsFeature struct {
	Calver string `default:"true"` // # 日历化尾部版本
}

type Fields struct {
	Package      string `default:"auto"`       // 软件包名称(自动, 使用 <?> 变量值)
	Version      string `default:"0.0.1"`      // 软件包版本(自动, 使用 <?> 变量值)
	Maintainer   string `default:"auto"`       // 软件包维护者(组织或个人)
	Architecture string `default:"auto"`       // 软件包架构(自动)
	Homepage     string `default:"auto"`       // 软件包主页(自动，使用 git 命令获取地址)
	Section      string `default:"devel"`      // 软件包属于的系统部分[admin|cli-mono|comm|database|debug|devel|doc|editors|education|electronics|embedded|fonts|games|gnome|gnu-r|gnustep|graphics|hamradio|haskell|httpd|interpreters|introspection|java|javascript|kde|kernel|libdevel|libs|lisp|localization|mail|math|metapackages|misc|net|news|ocaml|oldlibs|otherosfs|perl|php|python|ruby|rust|science|shells|sound|tasks|tex|text|utils|vcs|video|web|x11|xfce|zope]
	Priority     string `default:"optional"`   // 软件包优先级[required|important|stantard|optional|extra]
	Depends      string `default:""`           //  软件包依赖
	Description  string `default:"此包由二进制文件转化"` // 软件包描述信息
}
type PackageFileType int

const (
	File      PackageFileType = 0
	Directory PackageFileType = 1
)

type PackageFile struct {
	type0 PackageFileType

	spath string
	tpath string
}
type DebianPackage struct {
	Fields

	files []PackageFile
}

// AppendDir implements IDebianPackage.
func (d *DebianPackage) AppendDir(dir0 string, dir1 string) {
	d.files = append(d.files, PackageFile{
		type0: Directory,
		spath: dir0,
		tpath: dir1,
	})
}

// AppendFile implements IDebianPackage.
func (d *DebianPackage) AppendFile(file0 string, dir0 string) {
	d.files = append(d.files, PackageFile{
		type0: File,
		spath: file0,
		tpath: dir0,
	})
}

// AppendBinary implements IDebianBinaryPackage.
func (d *DebianPackage) AppendBinary(file0 string) {
	d.files = append(d.files, PackageFile{
		type0: File,
		spath: file0,
		tpath: "/usr/bin",
	})
}

func NewDebianPackage(name string) DebianPackage {
	return DebianPackage{
		Fields: Fields{
			Package:      name,
			Version:      "0.0.1",
			Maintainer:   "normal",
			Architecture: "all",
			Section:      "",
			Priority:     "",
			Depends:      "",
			Description:  "",
		},
		files: []PackageFile{},
	}
}

type Packager interface {
	SetWorkSpacke(dir string)
	Pack(pkg DebianPackage) error
}

// 使用 DebianPackager 进行打包工作处理
type DebianPackager struct {
	workdir string
}

func (d *DebianPackager) SetWorkSpacke(dir string) {
	d.workdir = dir
}

// Pack implements Packager.
func (d *DebianPackager) Pack(pkg DebianPackage) error {
	prefix := filepath.Join(d.workdir, pkg.Package)
	err := os.MkdirAll(prefix, os.FileMode(0755))
	if err != nil {
		return err
	}

	// mkdir DEBIAN
	os.MkdirAll(filepath.Join(prefix, "DEBIAN"), 0755)
	// mkdir usr
	os.MkdirAll(filepath.Join(prefix, "usr"), 0755)

	//control
	var control bytes.Buffer
	nfield := reflect.TypeOf(pkg.Fields).NumField()
	for i := 0; i < nfield; i++ {

		var field_name string
		var field_value string

		field := reflect.TypeOf(pkg.Fields).Field(i)
		default0 := field.Tag.Get("default")

		field_name = field.Name

		switch field.Name {
		case "Package":
			if default0 == "auto" {
				field_value = "binary-package"
			}

		case "Version":
		case "Maintainer":
		case "Architecture":
		case "Homepage":
		case "Section":
		case "Priority":
		case "Depends":
		case "Description":
		}

		line := fmt.Sprintf("%v: %v\n", field_name, field_value)
		control.WriteString(line)
	}

	for _, v := range pkg.files {
		if v.type0 == File {
			os.MkdirAll(filepath.Join(prefix, v.tpath), 0755)
		}
	}

	return nil
}

func NewDebianPackager() Packager {
	return &DebianPackager{
		workdir: "/tmp/debian-pack",
	}
}
